[Wireshark] sshdumpを使って手元のマシンからEC2インスタンスのパケットキャプチャーをしてみた
tcpdumpではなくてWiresharkでパケットを確認したいな
こんにちは、のんピ(@non____97)です。
皆さんはリモートのLinuxマシンをtcpdumpではなくて手元のマシンのWiresharkでパケットを確認したいなと思ったことはありますか? 私はあります。
tcpdumpで上手にフィルタリングをすれば良いのでしょうが、そうでなければ高速目grepすることとなり大変です。
そういった時は慣れ親しんだWiresharkが恋しくなるものです。
実はWiresharkでsshdump
を使えば、SSH越しにリモートコンピューターのパケットキャプチャーをすることはご存知でしょうか。
NAME
sshdump - Provide interfaces to capture from a remote host through SSH using a remote capture binary.
. . (中略) . .
DESCRIPTION
Sshdump is an extcap tool that allows one to run a remote capture tool over a SSH connection. The requirement is that the capture executable must have the capabilities to capture from the wanted interface.
これにより簡単にLinux系のマシンのパケットキャプチャーも手元のマシン上のWiresharkで行うことができます。
以下記事で紹介しているような特別なスクリプトは必要ありません。
これはありがたいですね。
試してみたので紹介します。
いきなりまとめ
- sshdumpを使えば手元のマシンからEC2インスタンスのパケットキャプチャーを簡単にできる
- Amazon Linux 2であればEC2インスタンスの設定変更は不要
- 適切なキャプチャーフィルターとディスプレイフィルターを設定しよう
検証環境
検証環境は以下の通りです。
Publicサブネット上にAmazon Linux 2のEC2インスタンスを起動させています。
EC2インスタンスにはキーペアを設定しており、インターネット越しにSSHで接続できるようにしています。また、インスタンスプロファイルのIAMロールにはAmazonSSMManagedInstanceCore
をアタッチしています。
手元のマシンのOSはMacです。WiresharkはHomebrewでインストールしました。その際にsshdumpも一緒にインストールされていました。
# macOSのバージョン > sw_vers ProductName: macOS ProductVersion: 13.0.1 BuildVersion: 22A400 # HomebrewでWiresharkをインストールした際の情報 > brew info wireshark ==> Downloading https://formulae.brew.sh/api/formula.jws.json ######################################################################## 100.0% ==> Downloading https://formulae.brew.sh/api/cask.jws.json ######################################################################## 100.0% Warning: Treating wireshark as a formula. For the cask, use homebrew/cask/wireshark ==> wireshark: stable 4.0.4 (bottled), HEAD Graphical network analyzer and capture tool https://www.wireshark.org Not installed From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/wireshark.rb License: GPL-2.0-or-later ==> Dependencies Build: cmake ✘ Required: c-ares ✔, glib ✔, gnutls ✔, libgcrypt ✔, libmaxminddb ✔, libnghttp2 ✔, libsmi ✔, libssh ✔, lua ✔ ==> Options --HEAD Install HEAD version ==> Caveats This formula only installs the command-line utilities by default. Install Wireshark.app with Homebrew Cask: brew install --cask wireshark If your list of available capture interfaces is empty (default macOS behavior), install ChmodBPF: brew install --cask wireshark-chmodbpf ==> Analytics install: 3,175 (30 days), 26,486 (90 days), 128,326 (365 days) install-on-request: 3,699 (30 days), 27,160 (90 days), 127,422 (365 days) build-error: 0 (30 days) # Wiresharkのバージョンの確認 > wireshark --version ** (wireshark:29217) 13:07:15.798439 [Epan WARNING] epan/prefs.c:4574 -- read_prefs_file(): Incomplete preference at line 25: of <ホームディレクトリ>/.config/wireshark/recent_common (save preferences to remove this warning) Wireshark 4.0.4 (v4.0.4-0-gea14d468d9ca). Copyright 1998-2023 Gerald Combs <[email protected]> and contributors. Licensed under the terms of the GNU General Public License (version 2 or later). This is free software; see the file named COPYING in the distribution. There is NO WARRANTY; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiled (64-bit) using Clang 13.0.0 (clang-1300.0.29.30), with GLib 2.68.4, with PCRE2, with zlib 1.2.11, with Qt 6.2.4, with libpcap, without POSIX capabilities, with Lua 5.2.4, with GnuTLS 3.6.15 and PKCS #11 support, with Gcrypt 1.8.7, with Kerberos (MIT), with MaxMind, with nghttp2 1.46.0, with brotli, with LZ4, with Zstandard, with Snappy, with libxml2 2.9.9, with libsmi 0.4.8, with QtMultimedia, with automatic updates using Sparkle, with SpeexDSP (using system library), with Minizip, with binary plugins. Running on macOS 13.0.1, build 22A400 (Darwin 22.1.0), with Apple M1 Max, with 32768 MB of physical memory, with GLib 2.68.4, with PCRE2 10.39 2021-10-29, with zlib 1.2.11, with Qt 6.2.4, with libpcap 1.10.1, with c-ares 1.15.0, with GnuTLS 3.6.15, with Gcrypt 1.8.7, with nghttp2 1.46.0, with brotli 1.0.9, with LZ4 1.9.2, with Zstandard 1.4.2, with libsmi 0.4.8, with LC_TYPE=ja_JP.UTF-8, binary plugins supported. # sshdumpのバージョン確認 > sshdump --version sshdump version 1.1.0 Compiled with libssh version 0.9.6 Running with libssh version 0.9.6/gnutls/zlib
やってみた
Wiresharkの設定変更
早速やってみましょう。
まずは設定変更です。
Wiresharkを起動して、SSH remote capture: sshdump
横の歯車マークをクリックします。
Server
タブからRemote SSH server address
でパケットキャプチャーしたいEC2インスタンスのグローバルIPアドレスを指定します。(Public DNS Nameでも良いです)
Authentication
タブからRemote SSH server username
でSSHする際のユーザー名を指定します。今回はAmazon Linux 2なのでec2-user
を指定しました。また、Path to SSH private key
でEC2インスタンスに設定したキーペアの秘密鍵を指定します。
Capture
タブからRemote capture filter
でキャプチャーフィルターを定義します。
ローカルマシンとEC2インスタンス間のSSHのパケットがノイズになるので、今回は以下のようなキャプチャーフィルターとしました。
not (host <ローカルマシンのグローバルIPアドレス> and port 22)
Debug
タブの設定値は特に変更しません。
設定変更は以上です。
パケットキャプチャーの実施
実際にパケットキャプチャーをしてみます。
SSH remote capture: sshdump
をクリックします。
すると、以下のように指定したEC2インスタンスのパケットキャプチャーができました。
非常に簡単ですね。
SSMセッションマネージャーのポートフォワーディングと連携してみた
EC2インスタンスがPublicサブネットにおらず、直接SSHできないこともあると思います。
その場合はSSMセッションマネージャーでSSHをポートフォワーディングしてから行います。
まず、以下のようにSSMセッションマネージャーでパケットキャプチャーをしたいEC2インスタンスのTCP/22を手元のマシンのTCP/10022にポートフォワーディングします。
> aws ssm start-session --target <EC2インスタンスのID> \ --document-name AWS-StartPortForwardingSession \ --parameters '{"portNumber":["22"],"localPortNumber":["10022"]}' Starting session with SessionId: botocore-session-1678685409-0458928fc23890866 Port 10022 opened for sessionId botocore-session-1678685409-0458928fc23890866. Waiting for connections...
Waiting for connections...
と表示されればOKです。
SSMポートフォワーディングができない場合は以下について確認をします。
- EC2インスタンスにSSM Agentがインストールされていること
- EC2インスタンスにSSM Agentが起動していること
- EC2インスタンスから以下エンドポイントの名前解決ができること
- ssm..amazonaws.com
- ssmmessages..amazonaws.com
- ec2messages..amazonaws.com
- EC2インスタンスから上述のエンドポイントにHTTPSでアクセスできること
AmazonSSMManagedInstanceCore
など適切なポリシーを持ったIAMロールがインスタンスプロファイルに割り当てられていること- ポートフォワーディング先のポートが別プロセスで使われていないこと
次にWiresharkの設定変更を行います。
SSH remote capture: sshdump
のServer
タブから接続先を変更します。TCP/22を手元のマシンのTCP/10022にポートフォワーディングしているので、Remote SSH server address
は127.0.0.1
でRemote SSH server port
は10022
です。
この状態でSSH remote capture: sshdump
をクリックすると、パケットキャプチャーが開始されます。
しかし、SSMセッションマネージャーでポートフォワーディングしている関係上、EC2インスタンスとSSMのエンドポイント間のパケットが大量に流れてしまい非常に辛いです。今回は15秒で11081パケットほどキャプチャーされています。
見た限りApplication Data
のパケットがほとんどでした。
こちらで使用しているIPアドレスを逆引きした結果、SOAレコードがAmazonのものだったため、こちらがSSMに関連するエンドポイントのIPアドレスだと推測します。
> dig -x 209.54.181.198 @8.8.8.8 ; <<>> DiG 9.10.6 <<>> -x 209.54.181.198 @8.8.8.8 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 801 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ;; QUESTION SECTION: ;198.181.54.209.in-addr.arpa. IN PTR ;; AUTHORITY SECTION: 181.54.209.in-addr.arpa. 900 IN SOA dns-external-master.amazon.com. root.amazon.com. 1 3600 900 604800 900 ;; Query time: 52 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Mon Mar 13 15:09:52 JST 2023 ;; MSG SIZE rcvd: 127
こちらの一連の通信以外のパケットのみを表示するように変更します。
Application Data
のTCPの情報を確認すると[Stream index: 0]
でした。こちらの一連の通信以外のパケットのみを表示するようにディスプレイフィルターでnot(tcp.stream eq 0)
を指定します。
これにより、4パケットのみ表示されるようになりました。
ただし、ディスプレイフィルターによるフィルタリングであるため、SSMのパケット自体はキャプチャーされ続けています。
確認したい通信がHTTPSではないのであれば、キャプチャーフィルターでnot (tcp port https)
と指定するのも良いと思います。
これによりキャプチャーサイズを抑えることができるようになります。
キャプチャーフィルターの構文を完全に理解したい場合はpcap-filterのマニュアルをご覧ください。
快適なWiresharkライフを
sshdumpを使って手元のマシン上のWiresharkからEC2インスタンスのパケットキャプチャーをしてみました。
非常に簡単にパケットキャプチャーできましたね。トラブルシューティングはもちろん、パケットを見てニヤニヤしたいなと言う衝動に駆られた際に役立ちます。
sshdumpの接続先マシンではtcpdumpもしくはdumpcapなどパケットキャプチャー用のソフトウェアが動作しています。もし、これらソフトウェアがインストールされていなければインストールしておきましょう。
この記事が誰かの助けになれば幸いです。
以上、AWS事業本部 コンサルティング部の のんピ(@non____97)でした!